package ruru.client.ui.widgets;

import ruru.client.RuruDkp;
import ruru.client.backend.RuruUtility;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

public class ItemLink extends Composite implements Comparable, MouseListener {
	private HorizontalPanel panel;
	private FocusPanel fp;
	// private Image itemIcon;
	private AbsolutePanel abs;
	private HTML label;
	private String name;

	private String itemName;

	private int x;
	private int y;

	// stores item information
	private String savedText;
	private String savedIconName;

	// timer for tooltip checking if it's been initialized
	private Timer timer;

	/**
	 * Makes sure tooltip is only shown after data has been received from the server. See RuruDkp.java Now moved to
	 * setStorage.
	 */
	private boolean textInit = false;
	private boolean imgInit = false;

	public ItemLink(String name) {
		this.itemName = name;
		String capitalized = RuruUtility.capitalize(RuruUtility.tokenizer(itemName));
		// this.label = new HTML("[" + captitalized + "]");
		this.label = new HTML(RuruUtility.convertToNBSP(capitalized));
		this.name = itemName;

		fp = new FocusPanel();
		fp.addMouseListener(this);

		savedText = "not set";
		savedIconName = "not set";
		timer = new Timer() {
			public void run() {
				if(textInit && imgInit) {
					showTooltip(x, y);
					cancel();
				}
			}
		};

		fp.addStyleName("item-link");
		RuruDkp.getTooltipInfo(wowheadUrl(), itemName, this);

		panel = new HorizontalPanel();
		panel.setSpacing(0);

		// itemIcon = new Image();
		// itemIcon.addStyleName("border-image");
		// itemIcon.setSize("24px", "24px");
		// abs = new AbsolutePanel();
		// abs.add(itemIcon);

		panel.setCellVerticalAlignment(label, HasVerticalAlignment.ALIGN_MIDDLE);
		panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		label.setStyleName("itemlink-icon-label");
		// panel.add(abs);
		panel.add(label);
		fp.add(panel);
		initWidget(fp);
	}

	// public void setIconFileName() {
	// DOM.setStyleAttribute(abs.getElement(), "backgroundImage", "url(http://www.wowhead.com/images/icons/medium/" +
	// name + ".jpg)");
	// DOM.setStyleAttribute(abs.getElement(), "backgroundPosition", "center");
	// DOM.setStyleAttribute(abs.getElement(), "backgroundRepeat", "no-repeat");
	// }

	public void setItemRarity(String rarityClass) {
		label.addStyleName(rarityClass);
	}

	public AbsolutePanel getAbs() {
		return abs;
	}

	public String toString() {
		return "[" + name + "]";
	}

	public String getName() {
		return name;
	}

	public String wowheadUrl() {
		return "http://wow.allakhazam.com/ihtml?" + itemName;
	}

	public void setStorage(String info) {
		this.savedText = info;
		textInit = true;
	}

	public void setIconStorage(String iconName) {
		this.savedIconName = iconName;
		imgInit = true;

		// itemIcon.setUrl("http://www.wowhead.com/images/icons/medium/" + iconName + ".jpg");
	}

	/**
	 * Makes sure tooltip is only shown after data has been received from the server. See RuruDkp.java Now moved to
	 * setStorage.
	 * 
	 * @param status
	 */
	// private void setInitStatus(boolean status) {
	// tooltipInitialized = status;
	// }
	public int compareTo(Object arg0) {
		if(!(arg0 instanceof ItemLink)) {
			return -1;
		} else {
			return label.getText().compareTo(((ItemLink) arg0).label.getText());
		}
	}

	public void onMouseDown(Widget sender, int x, int y) {
	// empty
	}

	public void onMouseEnter(final Widget sender) {
		if(!textInit || !imgInit) {
			// this code should not be called if stuffItemLink is called in constructor to pre-load
			RuruDkp.getTooltipInfo(wowheadUrl(), itemName, this);
			timer.scheduleRepeating(200);
		} else {
			showTooltip(x, y);
		}
	}

	public void onMouseLeave(Widget sender) {
		RuruDkp.tooltipPanel.setVisible(false);
		timer.cancel();
	}

	public void onMouseMove(Widget sender, int x, int y) {
		this.x = x;
		this.y = y;

		if(textInit && imgInit) {
			showTooltip(x, y);
		}
	}

	public void onMouseUp(Widget sender, int x, int y) {
	// empty
	}

	/**
	 * Calculates the position for the tooltip. Makes sure tooltip doesn't cause the screen to scroll vertically. Takes
	 * into account window scrolling.
	 */
	public void showTooltip(int x, int y) {
		// posX is the cursor's x coordinate
		int posX = getAbsoluteLeft() + x + scrollX();

		// posY is the position of the bottom of the current ItemLink, unless it's
		// too tall
		int posY = getAbsoluteTop() + 4;// + getOffsetHeight();

		// position offscreen so we can determine whether or not we need to
		// reposition due to tooltip exceeding the bottom border
		// RootPanel.get().setWidgetPosition(RuruDkp.rpTooltip, 2000, 2000);
		RuruDkp.tooltipPanel.setVisible(false);

		// set html contents so rpTooltip's measurement calculations below are
		// correct
		RuruDkp.tooltip.setHTML(savedText);
		DOM.setStyleAttribute(RuruDkp.itemIcon.getElement(), "backgroundImage",
				"url(http://www.wowhead.com/images/icons/medium/" + savedIconName.toLowerCase() + ".jpg)");
		RuruDkp.tooltipPanel.setVisible(true);

		/**
		 * double check to make sure tooltip doesn't overflow the tabpanel TODO: eliminate flicker - tooltip is set
		 * visible first, and then corrected
		 */
		int tooltipHeight = RuruDkp.tooltipPanel.getOffsetHeight();
		int mainRpBottom = RuruDkp.body.getOffsetHeight() + RuruDkp.body.getAbsoluteTop();
		int distanceFromBottom = 5;

		// restrict the tooltip from being taller than ruruDkp's rounded panel's
		// bottom
		if(posY + tooltipHeight > mainRpBottom) {
			posY = mainRpBottom - tooltipHeight;
			posY -= distanceFromBottom; // make it not perfectly even

			RootPanel.get().setWidgetPosition(RuruDkp.tooltipPanel, posX + 15, posY);
		}

		// add 30 to posX to give the cursor some room
		RootPanel.get().setWidgetPosition(RuruDkp.tooltipPanel, posX + 15, posY);

		RuruDkp.tooltipPanel.setVisible(true);

		if(RuruDkp.tooltipPanel.getOffsetWidth() > 350) {
			RuruDkp.tooltipPanel.setWidth("350px");
		} else {
			/**
			 * TODO the problem here is the containing panel expands to 350px after the first max width item shows up but
			 * never gets a chance to "drop back" to smaller widths.
			 */
		}
	}

	public native int scrollY() /*-{
	 return $doc.body.scrollTop;
	 }-*/;

	public native int scrollX() /*-{
	 return $doc.body.scrollLeft;
	 }-*/;
}